#pragma once

#include <cassert>
#include "Vec4.hpp"

namespace Alice
{

/*
    4 x 4 矩阵
    用作变换矩阵
*/
class Mat44
{
public:
    Mat44()
    {
        // 单位矩阵
        data[0][0] = 1.0f; data[0][1] = 0.0f; data[0][2] = 0.0f; data[0][3] = 0.0f;
		data[1][0] = 0.0f; data[1][1] = 1.0f; data[1][2] = 0.0f; data[1][3] = 0.0f;
		data[2][0] = 0.0f; data[2][1] = 0.0f; data[2][2] = 1.0f; data[2][3] = 0.0f;
		data[3][0] = 0.0f; data[3][1] = 0.0f; data[3][2] = 0.0f; data[3][3] = 1.0f;
    }

    Mat44(const Mat44& mat44)
    {
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                data[i][j] = mat44[i][j];
    }

    /*
        重载取值运算符 [] ，使其返回一维数组指针
        以支持使用 [][] 访问二维数组
    */
    float* operator[](unsigned int index)
    {
        assert(index < 4 && "Mat44 overflow!");
        
        return data[index];
    }

    const float* operator[](unsigned int index) const
    {
        assert(index < 4 && "Mat44 overflow!");
        
        return data[index];
    }

    /*
        重载基本数学运算符
    */
    Mat44 operator*(Mat44 const& mat44)
    {
        Mat44 result;

        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                float sum = 0.0f;
                for (int k = 0; k < 4; k++)
                {
                    sum += data[i][k] * mat44[k][j];
                }
                result[i][j] = sum;
            }
        }

        return result;
    }

    Vec4 operator*(Vec4 const& vec4)
    {
        Vec4 v4;
        
        v4.x = (vec4.x * data[0][0]) + (vec4.y * data[0][1]) + (vec4.z * data[0][2]) + (vec4.w * data[0][3]);
        v4.y = (vec4.x * data[1][0]) + (vec4.y * data[1][1]) + (vec4.z * data[1][2]) + (vec4.w * data[1][3]);
        v4.z = (vec4.x * data[2][0]) + (vec4.y * data[2][1]) + (vec4.z * data[2][2]) + (vec4.w * data[2][3]);
        v4.w = (vec4.x * data[3][0]) + (vec4.y * data[3][1]) + (vec4.z * data[3][2]) + (vec4.w * data[3][3]);
    
        return v4;
    }

<<<<<<< HEAD
=======
private:
>>>>>>> parent of 7977c7c (回退版本至未删除 glm 的版本)
    float data[4][4];
};

} // namespace Alice
